﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Windows.Media.Animation;

using AbstractFramework.Exceptions;
using AbstractFramework;
using AbstractFramework.Display;
using AbstractFramework.LogicControl;
using AbstractFramework.Constant;

namespace ControlLib
{
    /// <summary>
    /// Interaction logic for Elevator.xaml
    /// </summary>
    public partial class ElevatorDisplay : UserControl,IElevatorDisplay
    {
        private int floorsNum;
        //private int currentPos;
        private IElevator logicElevator;
        private ElevatorStatus elevatorState = ElevatorStatus.Stoped;
        private Storyboard storyBoard;
        private int objectPos;

        public ElevatorDisplay()
        {
            InitializeComponent();
        }

        public void initialize (int floorsNum, IElevator logicElevator)
        {
            this.floorsNum = floorsNum;
            this.logicElevator = logicElevator;
        }      
        public int getFloorsNum()
        {
            return floorsNum;
        }

        public ElevatorStatus getElevatorState()
        {
            return elevatorState;
        }

        //向上移动n层
        public void goUp(int n)
        {
            //检查状态是否满足
            if (elevatorState != ElevatorStatus.Stoped && elevatorState != ElevatorStatus.UpMoving)
            {
                throw new ElevatorStateErrorException("The elvatorState is not stoped!");
            }

            //检查是否越界
            if ( logicElevator.Floor+ n > floorsNum - 1)
            {
                throw new OutFloorException();
            }

            elevatorState = ElevatorStatus.UpMoving;
            this.objectPos = logicElevator.Floor + n;

            goUpOneFloor();

        }

        //向上移动一层
        private void goUpOneFloor()
        {
            //获取当前位置
            Thickness from = leftdoor.Margin;
            Thickness to = new Thickness(from.Left, from.Top, from.Right, (logicElevator.Floor + 1) * 100);//用Math.Floor()进行下取整

            if (storyBoard != null && storyBoard.GetCurrentState() == ClockState.Active)
            {
                storyBoard.Stop();
            }
            storyBoard = new Storyboard();

            //创建动画
            ThicknessAnimation thicknessAnimation = new ThicknessAnimation(from, to, new Duration(TimeSpan.FromMilliseconds((to.Bottom-from.Bottom) * 10)));
            Storyboard.SetTarget(thicknessAnimation, leftdoor);
            Storyboard.SetTargetProperty(thicknessAnimation, new PropertyPath(Rectangle.MarginProperty));
            storyBoard.Children.Add(thicknessAnimation);

            ThicknessAnimation thicknessAnimation1 = new ThicknessAnimation(from, to, new Duration(TimeSpan.FromMilliseconds((to.Bottom-from.Bottom) * 10)));
            Storyboard.SetTarget(thicknessAnimation1, rightdoor);
            Storyboard.SetTargetProperty(thicknessAnimation1, new PropertyPath(Rectangle.MarginProperty));
            storyBoard.Children.Add(thicknessAnimation1);
            //动画播放
            storyBoard.Completed += new EventHandler(goUpOneFloor_Completed);
            storyBoard.Begin();
        }

        //向上移动一层完毕
        void goUpOneFloor_Completed(object sender, EventArgs e)
        {
            this.logicElevator.onPositionChanged(logicElevator.Floor, logicElevator.Floor + 1);
            logicElevator.Floor+= 1;
            if (logicElevator.Floor < objectPos)
            {
                goUpOneFloor();
            }
            else
            {
                elevatorState = ElevatorStatus.Stoped;
                this.logicElevator.onArrived(logicElevator.Floor);
            }
        }

        //向下移动n层
        public void goDown(int n)
        {
            //检查状态是否满足
            if (elevatorState != ElevatorStatus.Stoped && elevatorState != ElevatorStatus.DownMoving)
            {
                throw new ElevatorStateErrorException("The elvatorState is not stoped!");
            }

            //检查是否达到顶端了
            if (logicElevator.Floor - n < 0)
            {
                throw new ElevatorStateErrorException();
            }
            elevatorState = ElevatorStatus.DownMoving;
            this.objectPos = logicElevator.Floor - n;
            goDownOneFloor();
        }

        //向下移动一层
        private void goDownOneFloor()
        {
            //获取当前位置
            Thickness from = leftdoor.Margin;
            //Thickness to = new Thickness(from.Left, from.Top, from.Right, (Math.Floor((from.Bottom - 100)/100))*100);//Math.Floor()下取整
            Thickness to = new Thickness(from.Left, from.Top, from.Right, (logicElevator.Floor - 1)*100);
            if (storyBoard != null && storyBoard.GetCurrentState() == ClockState.Active)
            {
                storyBoard.Stop();
            }
            storyBoard = new Storyboard();

            //创建动画
            ThicknessAnimation thicknessAnimation = new ThicknessAnimation(from, to, new Duration(TimeSpan.FromMilliseconds((from.Bottom - to.Bottom) * 10)));
            Storyboard.SetTarget(thicknessAnimation, leftdoor);
            Storyboard.SetTargetProperty(thicknessAnimation, new PropertyPath(Rectangle.MarginProperty));
            storyBoard.Children.Add(thicknessAnimation);

            ThicknessAnimation thicknessAnimation1 = new ThicknessAnimation(from, to, new Duration(TimeSpan.FromMilliseconds((from.Bottom - to.Bottom) * 10)));
            Storyboard.SetTarget(thicknessAnimation1, rightdoor);
            Storyboard.SetTargetProperty(thicknessAnimation1, new PropertyPath(Rectangle.MarginProperty));
            storyBoard.Children.Add(thicknessAnimation1);
            //动画播放
            storyBoard.Completed += new EventHandler(goDownOneFloor_Completed);
            storyBoard.Begin();
        }

        //向下移动一层完毕
        void goDownOneFloor_Completed(object sender, EventArgs e)
        {
            this.logicElevator.onPositionChanged(logicElevator.Floor, logicElevator.Floor - 1);
            logicElevator.Floor -= 1;
            if (logicElevator.Floor > objectPos)
            {
                goDownOneFloor();
            }
            else
            {
                elevatorState = ElevatorStatus.Stoped;
                this.logicElevator.onArrived(logicElevator.Floor);
            }
        }

        public void open(bool triggerEvent)
        {
            //检查状态是否满足
            if (elevatorState != ElevatorStatus.Stoped && elevatorState != ElevatorStatus.Closing)
            {
                //throw new ElevatorStateErrorException("The elevatorState is not stoped or closing!");
                //MessageBox.Show("The elevatorState is not stoped or closing!", "提示", MessageBoxButton.OK, MessageBoxImage.Warning);
                return;
            }
            elevatorState = ElevatorStatus.Opening;

            if (storyBoard != null && storyBoard.GetCurrentState() == ClockState.Active)
            {
                storyBoard.Stop();
            }
            storyBoard = new Storyboard();
            double originWidth = leftdoor.Width;
            //创建动画
            DoubleAnimation doubleAnimation = new DoubleAnimation(originWidth, 5, new Duration(TimeSpan.FromMilliseconds(1000 * (originWidth - 5) / 45)));
            Storyboard.SetTarget(doubleAnimation, leftdoor);
            Storyboard.SetTargetProperty(doubleAnimation, new PropertyPath(Rectangle.WidthProperty));
            storyBoard.Children.Add(doubleAnimation);

            DoubleAnimation doubleAnimation1 = new DoubleAnimation(originWidth, 5, new Duration(TimeSpan.FromMilliseconds(1000 * (originWidth - 5) / 45)));
            Storyboard.SetTarget(doubleAnimation1, rightdoor);
            Storyboard.SetTargetProperty(doubleAnimation1, new PropertyPath(Rectangle.WidthProperty));
            storyBoard.Children.Add(doubleAnimation1);

            storyBoard.Completed += new EventHandler(open_Completed);
            //如果需要触发事件
            if (triggerEvent)
            {
                storyBoard.Completed += new EventHandler(open_CompletedNotify);
            }
            //动画播放
            storyBoard.Begin();
        }

        void open_Completed(object sender, EventArgs e)
        {
            elevatorState = ElevatorStatus.Opened;

            int outPeo = RandomWithAverage(0, logicElevator.PeopleNum);
            logicElevator.PeopleNum -= outPeo;

            int inPeoLowBound = 0;//进去的人的下限是0
            int itPeoUpBound = SystemConstant.maxPeopleNum - logicElevator.PeopleNum;//进去的人的上限是当前电梯容量

            int inPeo = RandomWithAverage(inPeoLowBound, itPeoUpBound);
            logicElevator.PeopleNum += inPeo;

            logicElevator.Inside_Indicator.showRestroom(SystemConstant.maxPeopleNum - logicElevator.PeopleNum);

            SystemConstant.uniqueStatistic.updatePeopleSum(this.logicElevator.Id, inPeo);
        }

        private int RandomWithAverage(int low,int up)
        {
            Random rand = new Random();
            double randdouble = rand.NextDouble();
            int result = (int)Math.Floor((randdouble) * (up - low + 1) + low);
            return result;
        }

        //private int RandomWithGeometric(int PeoNum,int leftFloorsNum)
        //{
        //    Random rand = new Random(new DateTime().Millisecond);
        //    int result = 0;
        //    for (int i = 0; i < PeoNum; i++)
        //    {
        //        double temp = rand.NextDouble();
        //        if (temp < 1.0 / leftFloorsNum)
        //        {
        //            result++;
        //        }
        //    }
        //    return result;
        //}

        void open_CompletedNotify(object sender, EventArgs e)
        {
            this.logicElevator.onOpened();
        }

        public void close(bool triggerEvent)
        {
            //检查状态是否满足
            if (elevatorState != ElevatorStatus.Opened && elevatorState != ElevatorStatus.Opening)
            {
                //throw new ElevatorStateErrorException("The elvatorState is not opened or opening!");
                //MessageBox.Show("The elvatorState is not opened or opening!", "提示", MessageBoxButton.OK, MessageBoxImage.Warning);
                return;
            }
            elevatorState = ElevatorStatus.Closing;

            if (storyBoard != null && storyBoard.GetCurrentState() == ClockState.Active)
            {
                storyBoard.Stop();
            }
            storyBoard = new Storyboard();
            double originWidth = leftdoor.Width;
            //创建动画
            DoubleAnimation doubleAnimation = new DoubleAnimation(originWidth, 50, new Duration(TimeSpan.FromMilliseconds(1000 * (50 - originWidth) / 45)));
            Storyboard.SetTarget(doubleAnimation, leftdoor);
            Storyboard.SetTargetProperty(doubleAnimation, new PropertyPath(Rectangle.WidthProperty));
            storyBoard.Children.Add(doubleAnimation);

            DoubleAnimation doubleAnimation1 = new DoubleAnimation(originWidth, 50, new Duration(TimeSpan.FromMilliseconds(1000 * (50 - originWidth) / 45)));
            Storyboard.SetTarget(doubleAnimation1, rightdoor);
            Storyboard.SetTargetProperty(doubleAnimation1, new PropertyPath(Rectangle.WidthProperty));
            storyBoard.Children.Add(doubleAnimation1);

            storyBoard.Completed += new EventHandler(close_Completed);
            //如果需要触发事件
            if (triggerEvent)
            {
                storyBoard.Completed += new EventHandler(close_CompletedNotify);
            }
            //动画播放
            storyBoard.Begin();
        }

        void close_Completed(object sender, EventArgs e)
        {
            elevatorState = ElevatorStatus.Stoped;
        }

        void close_CompletedNotify(object sender, EventArgs e)
        {
            this.logicElevator.onClosed();
        }

        private void UserControl_Loaded(object sender, System.Windows.RoutedEventArgs e)
        {
            this.Height = 100 * floorsNum;
            for (int i = 1; i <= floorsNum; i++)
            {
                TextBlock newText = new TextBlock();                              //创建按钮对象
                newText.Margin = new Thickness(0, 0, 0, 100 * (i - 1));
                newText.VerticalAlignment = VerticalAlignment.Bottom;
                newText.Width = 100;                                   //设置按钮宽度
                newText.Height = 100;                                       //设置按钮高度
                newText.TextAlignment = TextAlignment.Center;
                newText.Padding = new Thickness(0, 20, 0, 0);
                newText.FontFamily = new FontFamily("华文彩云");
                newText.FontSize = 64;
                newText.Foreground = new SolidColorBrush(Colors.DimGray);
                newText.Text = String.Format("{0}", i);                                  //设置按钮文本内容
                gridAll.Children.Insert(0, newText);                               //添加到Grid控件
                newText.SetValue(Grid.RowProperty, 0);                      //设置按钮所在Grid控件的行
                newText.SetValue(Grid.ColumnProperty, 0);              //设置按钮所在Grid控件的列
                newText.SetValue(Grid.ColumnSpanProperty, 2);
            }
        }
    }
}
